﻿#include "function_dump.h"

void bump(HObject ho_image, HObject *ho_region_error, HObject *ho_region_line, HObject *ho_region_cross,
	HTuple hv_row1, HTuple hv_column1, HTuple hv_row2, HTuple hv_column2, HTuple hv_count,
	HTuple hv_space, HTuple hv_position, HTuple hv_transition, HTuple hv_threshold,
	HTuple hv_standard_left_min, HTuple hv_standard_left_max, HTuple hv_standard_right_min,
	HTuple hv_standard_right_max, HTuple *hv_defect_value, HTuple *hv_ret)
{

	// Local iconic variables
	HObject  ho_ROI, ho_Contours, ho_RegionCross;
	HObject  ho_Contour, ho_RegionLine, ho_RegionError;

	// Local control variables
	HTuple  hv_Height, hv_Width, hv_Index, hv_low;
	HTuple  hv_high, hv_shapeParam, hv_MetrologyHandle, hv_IndexMetrology;
	HTuple  hv_Row, hv_Column, hv_RowBegin, hv_ColBegin, hv_RowEnd;
	HTuple  hv_ColEnd, hv_Nr, hv_Nc, hv_Dist, hv_D, hv_RowLeft;
	HTuple  hv_ColumnLeft, hv_RowRight, hv_ColumnRight, hv_IndexLeftRight;
	HTuple  hv_DistanceLeft, hv_DistanceLeftMax, hv_DistanceLeftIndices;
	HTuple  hv_RowLeftMax, hv_ColumnLeftMax, hv_RowProj, hv_ColProj;
	HTuple  hv_DistanceRight, hv_DistanceRightMax, hv_DistanceRightIndices;
	HTuple  hv_RowRightMax, hv_ColumnRightMax, hv_region_errorNumber;

	GenEmptyObj(&(*ho_region_error));
	GenEmptyObj(&(*ho_region_line));
	GenEmptyObj(&(*ho_region_cross));

	hv_Height = hv_row2 - hv_row1;
	hv_Width = hv_column2 - hv_column1;
	{
		HTuple end_val6 = hv_count - 1;
		HTuple step_val6 = 1;
		for (hv_Index = 0; hv_Index.Continue(end_val6, step_val6); hv_Index += step_val6)
		{
			hv_low = hv_row1 + ((hv_Index*hv_Height) / hv_count);
			hv_high = hv_row1 + (((hv_Index + 1)*hv_Height) / hv_count);
			GenRectangle1(&ho_ROI, hv_low, hv_column1, hv_high, hv_column2);

			hv_shapeParam.Clear();
			hv_shapeParam.Append(hv_high);
			hv_shapeParam.Append((hv_column1 + hv_column2) / 2);
			hv_shapeParam.Append(hv_low);
			hv_shapeParam.Append((hv_column1 + hv_column2) / 2);

			//创建句柄
			CreateMetrologyModel(&hv_MetrologyHandle);
			SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);

			//添加线模型
			AddMetrologyObjectGeneric(hv_MetrologyHandle, "line", hv_shapeParam, (hv_column2 - hv_column1) / 2,
				1, 1, hv_threshold, HTuple(), HTuple(), &hv_IndexMetrology);

			//设置参数，这里根据自己需求设置，这一坨用的都是同一个算子
			if (0 != (int(hv_transition == 0)))
			{
				SetMetrologyObjectParam(hv_MetrologyHandle, "all", "measure_transition", "positive");
			}
			else
			{
				SetMetrologyObjectParam(hv_MetrologyHandle, "all", "measure_transition", "negative");
			}

			if (0 != (int(hv_position == 0)))
			{
				SetMetrologyObjectParam(hv_MetrologyHandle, "all", "measure_select", "first");
			}
			else
			{
				SetMetrologyObjectParam(hv_MetrologyHandle, "all", "measure_select", "last");
			}


			SetMetrologyObjectParam(hv_MetrologyHandle, "all", "measure_distance", hv_space);


			//开始找边缘，顺便把边缘上卡尺找到的所有点坐标输出在ROW,Column里面（数组形式）
			ApplyMetrologyModel(ho_image, hv_MetrologyHandle);
			GetMetrologyObjectMeasures(&ho_Contours, hv_MetrologyHandle, 0, "all", &hv_Row,
				&hv_Column);

			//把点显示出来
			GenCircle(&ho_RegionCross, hv_Row, hv_Column, 1);

			//释放测量句柄
			ClearMetrologyModel(hv_MetrologyHandle);


			GenContourPolygonXld(&ho_Contour, hv_Row, hv_Column);

			FitLineContourXld(ho_Contour, "tukey", -1, 0, 5, 2, &hv_RowBegin, &hv_ColBegin,
				&hv_RowEnd, &hv_ColEnd, &hv_Nr, &hv_Nc, &hv_Dist);



			GenRegionLine(&ho_RegionLine, hv_RowBegin, hv_ColBegin, hv_RowEnd, hv_ColEnd);

			hv_D = ((((hv_ColBegin - hv_ColEnd) / (hv_RowBegin - hv_RowEnd))*(hv_Row - hv_RowEnd)) + hv_ColEnd) - hv_Column;

			hv_RowLeft = HTuple();
			hv_ColumnLeft = HTuple();

			hv_RowRight = HTuple();
			hv_ColumnRight = HTuple();

			{
				HTuple end_val64 = (hv_D.TupleLength()) - 1;
				HTuple step_val64 = 1;
				for (hv_IndexLeftRight = 0; hv_IndexLeftRight.Continue(end_val64, step_val64); hv_IndexLeftRight += step_val64)
				{
					if (0 != (int(HTuple(hv_D[hv_IndexLeftRight]) > 0)))
					{
						hv_RowLeft = hv_RowLeft.TupleConcat(HTuple(hv_Row[hv_IndexLeftRight]));
						hv_ColumnLeft = hv_ColumnLeft.TupleConcat(HTuple(hv_Column[hv_IndexLeftRight]));
					}
					else
					{
						hv_RowRight = hv_RowRight.TupleConcat(HTuple(hv_Row[hv_IndexLeftRight]));
						hv_ColumnRight = hv_ColumnRight.TupleConcat(HTuple(hv_Column[hv_IndexLeftRight]));
					}
				}
			}

			if (0 != (int((hv_RowLeft.TupleLength()) > 0)))
			{
				DistancePl(hv_RowLeft, hv_ColumnLeft, hv_RowBegin, hv_ColBegin, hv_RowEnd,
					hv_ColEnd, &hv_DistanceLeft);
				TupleMax(hv_DistanceLeft, &hv_DistanceLeftMax);
				if (0 != (HTuple(int(hv_DistanceLeftMax > hv_standard_left_max)).TupleOr(int(hv_DistanceLeftMax < hv_standard_left_min))))
				{
					TupleFind(hv_DistanceLeft, hv_DistanceLeftMax, &hv_DistanceLeftIndices);
					hv_RowLeftMax = HTuple(hv_RowLeft[hv_DistanceLeftIndices]);
					hv_ColumnLeftMax = HTuple(hv_ColumnLeft[hv_DistanceLeftIndices]);
					ProjectionPl(hv_RowLeftMax, hv_ColumnLeftMax, hv_RowBegin, hv_ColBegin, hv_RowEnd,
						hv_ColEnd, &hv_RowProj, &hv_ColProj);
					GenRegionLine(&ho_RegionError, hv_RowLeftMax, hv_ColumnLeftMax, hv_RowProj,
						hv_ColProj);
					(*hv_defect_value) = -1 * hv_DistanceLeftMax;
					Union2(ho_RegionError, (*ho_region_error), &(*ho_region_error));
					Union2(ho_RegionLine, (*ho_region_line), &(*ho_region_line));
					Union2(ho_RegionCross, (*ho_region_cross), &(*ho_region_cross));
					//ret := 0
					//return ()
				}
			}

			if (0 != (int((hv_RowRight.TupleLength()) > 0)))
			{
				DistancePl(hv_RowRight, hv_ColumnRight, hv_RowBegin, hv_ColBegin, hv_RowEnd,
					hv_ColEnd, &hv_DistanceRight);
				TupleMax(hv_DistanceRight, &hv_DistanceRightMax);
				if (0 != (HTuple(int(hv_DistanceRightMax > hv_standard_right_max)).TupleOr(int(hv_DistanceRightMax < hv_standard_right_min))))
				{
					TupleFind(hv_DistanceRight, hv_DistanceRightMax, &hv_DistanceRightIndices);
					hv_RowRightMax = HTuple(hv_RowRight[hv_DistanceRightIndices]);
					hv_ColumnRightMax = HTuple(hv_ColumnRight[hv_DistanceRightIndices]);
					ProjectionPl(hv_RowRightMax, hv_ColumnRightMax, hv_RowBegin, hv_ColBegin,
						hv_RowEnd, hv_ColEnd, &hv_RowProj, &hv_ColProj);
					GenRegionLine(&ho_RegionError, hv_RowRightMax, hv_ColumnRightMax, hv_RowProj,
						hv_ColProj);
					(*hv_defect_value) = hv_DistanceRightMax;
					Union2(ho_RegionError, (*ho_region_error), &(*ho_region_error));
					Union2(ho_RegionLine, (*ho_region_line), &(*ho_region_line));
					Union2(ho_RegionCross, (*ho_region_cross), &(*ho_region_cross));
					//ret := 0
					//return ()
				}
			}
		}
	}

	CountObj((*ho_region_error), &hv_region_errorNumber);

	if (0 != (int(hv_region_errorNumber > 0)))
	{
		(*hv_ret) = 0;
	}
	else
	{
		(*hv_ret) = 1;
	}

	return;



}




FunctionDump::FunctionDump(QDialog* parent, QSettings* qsettings, QString section) : QDialog(parent)
{
    m_qsettings = qsettings;
    m_section = section;

    this->setWindowTitle(("Dump"));
    QRect desktop_rect = QApplication::desktop()->geometry();
    double ratio_x = desktop_rect.width()/1920.0;
    double ratio_y = desktop_rect.height()/1080.0;

    move(0,0);
    setFixedSize(1920*ratio_x,1010*ratio_y);

    m_view = new MyQGraphicsView(this);
    m_view->setGeometry(660 * ratio_x, 0, 1250 * ratio_x, 940 * ratio_y);

    m_view->m_graphics_shape_rect = new GraphicsShapeRect(100, 100, 100, 100,Qt::blue);
    m_view->m_scene->addItem(m_view->m_graphics_shape_rect);
    QRectF qrectf = m_view->m_graphics_shape_rect->boundingRect();
    connect(m_view->m_graphics_shape_rect, &GraphicsShapeRect::sendMessage, m_view->m_pixmapItem, &MyQGraphicsPixmapItem::receiveMessage);

    Row1 = (int)qrectf.y();
    Column1 = (int)qrectf.x();
    Row2 = (int)(qrectf.y() + qrectf.height());
    Column2 = (int)(qrectf.x() + qrectf.width());
    QSize control_size(150*ratio_x,40*ratio_y);

    QWidget* p = new QWidget(this);
    p->move(0*ratio_x,0*ratio_y);
    p->setFixedSize(600*ratio_x,800*ratio_y);

    QGridLayout *qgridLayout = new QGridLayout();
    p->setLayout(qgridLayout);

    int index = 0;

    QSize ButtonSize(220 * ratio_x, 40 * ratio_y);

  
    /*m_qlabel_detection_count = new QLabel();
    m_qlabel_detection_count->setText("AreaCount");
    m_qlabel_detection_count->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_detection_count,index,0);
    m_qspinbox_detection_count = new QSpinBox();
    m_qspinbox_detection_count->setFixedSize(control_size);
    m_qspinbox_detection_count->setMinimum(1);
    m_qspinbox_detection_count->setMaximum(24);
    qgridLayout->addWidget(m_qspinbox_detection_count, index, 1);
    index++;*/

	
    /*m_qlabel_space = new QLabel();
    m_qlabel_space->setText("EdgeSpace");
    m_qlabel_space->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_space,index,0);
    m_qspinbox_space = new QSpinBox();
    m_qspinbox_space->setFixedSize(control_size);
    m_qspinbox_space->setMinimum(1);
    m_qspinbox_space->setMaximum(24);
    qgridLayout->addWidget(m_qspinbox_space, index, 1);
    index++;*/

    /*m_qlabel_position = new QLabel();
    m_qlabel_position->setText("EdgeType");
    m_qlabel_position->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_position,index,0);
    m_qcombox_position = new QComboBox();
    m_qcombox_position->setFixedSize(control_size);
    m_qcombox_position->addItem("Left");
    m_qcombox_position->addItem("Right");
    qgridLayout->addWidget(m_qcombox_position, index, 1);
    index++;*/


   /* m_qlabel_transition = new QLabel();
    m_qlabel_transition->setText("EdgePolarity");
    m_qlabel_transition->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_transition,index,0);
    m_qcombox_transition = new QComboBox();
    m_qcombox_transition->setFixedSize(control_size);
    m_qcombox_transition->addItem("Dark To Light");
    m_qcombox_transition->addItem("Light To Dark");
    qgridLayout->addWidget(m_qcombox_transition, index, 1);
    index++;*/


    /*m_qlabel_edge_threshold = new QLabel();
    m_qlabel_edge_threshold->setText("ContrastThreshold");
    m_qlabel_edge_threshold->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_edge_threshold, index, 0);
    m_qspinbox_edge_threshold = new QSpinBox();
    m_qspinbox_edge_threshold->setFixedSize(control_size);
    m_qspinbox_edge_threshold->setMinimum(5);
    m_qspinbox_edge_threshold->setMaximum(255);
    qgridLayout->addWidget(m_qspinbox_edge_threshold, index, 1);
    index++;*/

	m_qlabel_standard_left_min = new QLabel();
	m_qlabel_standard_left_min->setText("Left Min");
	m_qlabel_standard_left_min->setFixedSize(control_size);
	qgridLayout->addWidget(m_qlabel_standard_left_min, index, 0);
	m_qspinbox_standard_left_min = new QSpinBox();
	m_qspinbox_standard_left_min->setFixedSize(control_size);
	m_qspinbox_standard_left_min->setMinimum(0);
	m_qspinbox_standard_left_min->setMaximum(10000);
	qgridLayout->addWidget(m_qspinbox_standard_left_min, index, 1);
	index++;

    m_qlabel_standard_left_max = new QLabel();
    m_qlabel_standard_left_max->setText("Left Max");
    m_qlabel_standard_left_max->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_standard_left_max, index, 0);
    m_qspinbox_standard_left_max = new QSpinBox();
    m_qspinbox_standard_left_max->setFixedSize(control_size);
    m_qspinbox_standard_left_max->setMinimum(0);
    m_qspinbox_standard_left_max->setMaximum(10000);
    qgridLayout->addWidget(m_qspinbox_standard_left_max, index, 1);
    index++;

	m_qlabel_standard_right_min = new QLabel();
	m_qlabel_standard_right_min->setText("Right Min");
	m_qlabel_standard_right_min->setFixedSize(control_size);
	qgridLayout->addWidget(m_qlabel_standard_right_min, index, 0);
	m_qspinbox_standard_right_min = new QSpinBox();
	m_qspinbox_standard_right_min->setFixedSize(control_size);
	m_qspinbox_standard_right_min->setMinimum(0);
	m_qspinbox_standard_right_min->setMaximum(10000);
	qgridLayout->addWidget(m_qspinbox_standard_right_min, index, 1);
	index++;


    m_qlabel_standard_right_max = new QLabel();
    m_qlabel_standard_right_max->setText("Right Max");
    m_qlabel_standard_right_max->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_standard_right_max, index, 0);
    m_qspinbox_standard_right_max = new QSpinBox();
    m_qspinbox_standard_right_max->setFixedSize(control_size);
    m_qspinbox_standard_right_max->setMinimum(0);
    m_qspinbox_standard_right_max->setMaximum(10000);
    qgridLayout->addWidget(m_qspinbox_standard_right_max, index, 1);
    index++;

    m_pushbutton_save_parameter = new QPushButton(this);
    m_pushbutton_save_parameter->setFixedSize(control_size);
    m_pushbutton_save_parameter->setText("Save");
    connect(m_pushbutton_save_parameter, &QPushButton::clicked, this, &FunctionDump::saveParameter);
    qgridLayout->addWidget(m_pushbutton_save_parameter, index,0);

    index++;
	m_pushbutton_show_orign_image = new QPushButton(this);
	m_pushbutton_show_orign_image->setFixedSize(control_size);
    m_pushbutton_show_orign_image->setText("ShowOrign");
	connect(m_pushbutton_show_orign_image, &QPushButton::clicked, this, [=]() {
		QImage q_image = matToQImage(m_image);
		m_view->setImage(q_image, "");
		return true;
	});
	qgridLayout->addWidget(m_pushbutton_show_orign_image, index, 0);

	m_pushbutton_detection = new QPushButton(this);
	m_pushbutton_detection->setFixedSize(control_size);
    m_pushbutton_detection->setText("Detection");
	connect(m_pushbutton_detection, &QPushButton::clicked, this, &FunctionDump::detectionImage);
	qgridLayout->addWidget(m_pushbutton_detection, index, 1);
    
    index++;
    m_pushbutton_return = new QPushButton(this);
    m_pushbutton_return->setFixedSize(control_size);
    m_pushbutton_return->setText("Exit");
    qgridLayout->addWidget(m_pushbutton_return, index, 0);
    connect(m_pushbutton_return, &QPushButton::clicked, this, [=]() {
        this->hide();
        });
    loadParameter();
}

FunctionDump::~FunctionDump()
{
    ;
}

bool FunctionDump::detection( HObject image_in, QString& message)
{
    try
    {
		HTuple hv_max_value, hv_ret;
        bump(image_in, &m_region_error, &m_region_line, &m_region_cross,Row1, Column1, Row2, Column2, m_detection_count,m_space,m_positon,m_transition,m_edge_threshold, m_standard_left_min, m_standard_left_max,m_standard_right_min,m_standard_right_max,&hv_max_value,&hv_ret);

		

		int ret = hv_ret[0].I();
		
		if(ret>0)
		{
			return true;
        }
        else
        {
			double max_value = hv_max_value[0].D();
			message = "distance:" + QString::number(max_value);
            return false;
        }
    }
	catch (HException &HDevExpDefaultException)
	{
		message = HDevExpDefaultException.ErrorMessage();
		return false;
	}
  
    return true;
}

void FunctionDump::detectionImage()
{
    if(m_image.empty())
    {
        QMessageBox::information(nullptr,"","no image");
        return;
    }

    QString message;
    HObject image = matToHImage(m_image);
    bool state = detection(image, message);

	if (state)
		message += "OK";
	else
		message += "NG";

    Mat image_show = m_image.clone();
    if(image_show.empty())
    {
        QMessageBox::information(nullptr,"","no image");
        return;
    }
    draw(image_show, image_show);

    QImage q_image = matToQImage(image_show);

    m_view->setImage(q_image, message);
    
    }

void FunctionDump::draw(Mat image_in,Mat& image_out)
{
    if(image_in.empty())
        return;
	if (image_in.channels() == 1)
	{
		cvtColor(image_in, image_in, COLOR_GRAY2BGR);
	}
    image_out = drawRegionFill(image_in, m_region_line, Scalar(255, 0, 0));
    GenEmptyRegion(&m_region_line);

    image_out = drawRegion(image_out, m_region_cross, Scalar(0, 255, 0));
    GenEmptyRegion(&m_region_cross);

    image_out = drawRegion(image_out, m_region_error, Scalar(0, 0, 255));
    GenEmptyRegion(&m_region_error);
}

void FunctionDump::loadParameter()
{
    Row1 = m_qsettings->value(m_section + "/" + "Row1",10).toInt();
    Column1 = m_qsettings->value(m_section + "/" + "Column1",10).toInt();
    Row2 = m_qsettings->value(m_section + "/" + "Row2",5000).toInt();
    Column2 = m_qsettings->value(m_section + "/" + "Column2",500).toInt();
    m_view->setRectPose(Row1, Column1, Row2, Column2);

	m_detection_count = m_qsettings->value(m_section + "/" + "m_detection_count",1).toInt();
    //m_space   = m_qsettings->value(m_section + "/" + "m_space").toInt();
/*    m_positon = m_qsettings->value(m_section + "/" + "m_positon").toInt();
    m_transition = m_qsettings->value(m_section + "/" + "m_transition").toInt(); */ 
    /*m_edge_threshold = m_qsettings->value(m_section + "/" + "m_edge_threshold",10).toInt();*/
	m_standard_left_min = m_qsettings->value(m_section + "/" + "m_standard_left_min", 1).toInt();
	m_standard_right_min = m_qsettings->value(m_section + "/" + "m_standard_right_min").toInt();

	m_standard_left_max = m_qsettings->value(m_section + "/" + "m_standard_left_max",1).toInt();
    m_standard_right_max = m_qsettings->value(m_section + "/" + "m_standard_right_max").toInt();

    //m_qspinbox_detection_count->setValue(m_detection_count);
    //m_qspinbox_space->setValue(m_space);
    /*m_qcombox_position->setCurrentIndex(m_positon);
    m_qcombox_transition->setCurrentIndex(m_transition);*/
    /*m_qspinbox_edge_threshold->setValue(m_edge_threshold);*/

	m_qspinbox_standard_left_min->setValue(m_standard_left_min);
	m_qspinbox_standard_right_min->setValue(m_standard_right_min);

    m_qspinbox_standard_left_max->setValue(m_standard_left_max);
    m_qspinbox_standard_right_max->setValue(m_standard_right_max);
    return ;
}

void FunctionDump::saveParameter()
{
    QRectF qrectf = m_view->m_graphics_shape_rect->boundingRect();
    Row1 = m_view->m_graphics_shape_rect->pos().y() + (int)qrectf.y();
    Column1 = m_view->m_graphics_shape_rect->pos().x() + (int)qrectf.x();
    Row2 = m_view->m_graphics_shape_rect->pos().y() + (int)(qrectf.y() + qrectf.height());
    Column2 = m_view->m_graphics_shape_rect->pos().x() + (int)(qrectf.x() + qrectf.width());
    m_qsettings->setValue(m_section + "/" + "Row1", Row1);
    m_qsettings->setValue(m_section + "/" + "Column1", Column1);
    m_qsettings->setValue(m_section + "/" + "Row2", Row2);
    m_qsettings->setValue(m_section + "/" + "Column2", Column2);

    //m_detection_count = m_qspinbox_detection_count->value();
    //m_space  = m_qspinbox_space->value();
    /*m_positon=m_qcombox_position->currentIndex();
    m_transition= m_qcombox_transition->currentIndex();*/
    /*m_edge_threshold= m_qspinbox_edge_threshold->value();*/

	m_standard_left_min = m_qspinbox_standard_left_min->value();
	m_standard_right_min = m_qspinbox_standard_right_min->value();

	m_standard_left_max = m_qspinbox_standard_left_max->value();
    m_standard_right_max = m_qspinbox_standard_right_max->value();



    m_qsettings->setValue(m_section + "/" + "m_detection_count", m_detection_count);
    //m_qsettings->setValue(m_section + "/" + "m_space", m_space);
    //m_qsettings->setValue(m_section + "/" + "m_positon", m_positon);
    //m_qsettings->setValue(m_section + "/" + "m_transition", m_transition);
    /*m_qsettings->setValue(m_section + "/" + "m_edge_threshold", m_edge_threshold);*/

	m_qsettings->setValue(m_section + "/" + "m_standard_left_min", m_standard_left_min);
	m_qsettings->setValue(m_section + "/" + "m_standard_right_min", m_standard_right_min);

    m_qsettings->setValue(m_section + "/" + "m_standard_left_max", m_standard_left_max);
    m_qsettings->setValue(m_section + "/" + "m_standard_right_max", m_standard_right_max);



    
    return;
}

bool FunctionDump::showDialog()
{
    QImage q_image = matToQImage(m_image);
    m_view->setImage(q_image, "");
   
    return true;
}


